﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using NUnit.Framework;
using Smith.AMC.Network;

namespace MemcachedClientTests
{
    [TestFixture]
    public class ServerLocatorTest
    {
        private ServerLocator serverLocator;

        [TestFixtureSetUp]
        public void PerTestSetUp()
        {

            List<IMemcachedServerNode> memcachedServers = new List<IMemcachedServerNode>();
            memcachedServers.Add(
                new MemcachedServerNode(
                    IPAddress.Parse("127.0.0.1"),
                    11211,
                    SocketType.Stream,
                    ProtocolType.Tcp,
                    25,
                    0));
            memcachedServers.Add(
                new MemcachedServerNode(
                    IPAddress.Parse("127.0.0.1"),
                    11222,
                    SocketType.Stream,
                    ProtocolType.Tcp,
                    25,
                    1));
            memcachedServers.Add(
               new MemcachedServerNode(
                   IPAddress.Parse("127.0.0.1"),
                   11223,
                   SocketType.Stream,
                   ProtocolType.Tcp,
                   25,
                   2));
            memcachedServers.Add(
              new MemcachedServerNode(
                  IPAddress.Parse("127.0.0.1"),
                  11224,
                  SocketType.Stream,
                  ProtocolType.Tcp,
                  25,
                  3));
            memcachedServers.Add(
              new MemcachedServerNode(
                  IPAddress.Parse("127.0.0.1"),
                  11225,
                  SocketType.Stream,
                  ProtocolType.Tcp,
                  25,
                  4));
            serverLocator = new ServerLocator(memcachedServers);
        }

        [Test]
        public void count()
        {
            int serverPermutations = 200;
            for (int x = 0; x < 3; x++)
            {
                for (int y = 0; y < serverPermutations; y++)
                {
                    Console.WriteLine(y + (x * serverPermutations));
                }
            }
        }

        [Test]
        public void LocateServerShouldReturnAServer()
        {
            IMemcachedServerNode memcachedServerNode = serverLocator.LocateServer("omg");
            Assert.That(memcachedServerNode, Is.Not.Null);
        }

        [Test]
        public void LocateServerShouldGiveSameServerForTheSameKeyAlways()
        {
            IMemcachedServerNode memcachedServerNode = serverLocator.LocateServer("omg");
            for (int x = 0; x < 5000; x++)
            {
                IMemcachedServerNode memcachedServer2 = serverLocator.LocateServer("omg");
                Assert.That(memcachedServerNode, Is.SameAs(memcachedServer2));
            }
        }

        [Test]
        public void LocateServerShouldGiveOutDifferentServers()
        {
            Dictionary<IMemcachedServerNode, long> serverNumbers = new Dictionary<IMemcachedServerNode, long>();

            ServerLocator locator = CreateServerLocator(15);

            for (int x = 0; x < 5000; x++)
            {
                IMemcachedServerNode memcachedServerNode = locator.LocateServer("CK_CONTACTS_" + x);
                if (!serverNumbers.ContainsKey(memcachedServerNode))
                {
                    serverNumbers.Add(memcachedServerNode, 1);
                }

                serverNumbers[memcachedServerNode] += 1;
            }

            foreach (MemcachedServerNode server in serverNumbers.Keys)
            {
                Console.WriteLine(serverNumbers[server]);
                Assert.That(serverNumbers[server], Is.GreaterThan(0));
            }
        }

        private ServerLocator CreateServerLocator(int numberOfServers)
        {

            return new ServerLocator(CreateListOfServer(numberOfServers));
        }

        private List<IMemcachedServerNode> CreateListOfServer(int numberOfServers)
        {
            List<IMemcachedServerNode> memcachedServers = new List<IMemcachedServerNode>();
            for (int x = 0; x < numberOfServers; x++)
            {
                memcachedServers.Add(
                    new MemcachedServerNode(
                        IPAddress.Parse("127.0.0.1"),
                        11211 + x,
                        SocketType.Stream,
                        ProtocolType.Tcp,
                        25,
                        x));
            }
            return memcachedServers;
        }
    }
}
